﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
using UnityEngine;
using MVCF.Utilities;
using System.Reflection;
using System.Globalization;
using Verse.Sound;

namespace Miao.Stand
{
    public class StarPlatinumStand : StandPawn, ITheWorldStand
    {
        public float reboundProjectile;
        private bool theWorld = false;
        public override bool IsMeleeStand => true;
        public bool TheWorld { get => theWorld; set => theWorld = value; }
        public override void InitStandAbility()
        {
            base.InitStandAbility();
            standAbilityTracker.standAbilities.Add(StandAbilityMaker.CreateStandAbility("TheWorld", this));

            FieldInfo tracker =  owner.GetType().GetField("drawer", BindingFlags.NonPublic | BindingFlags.Instance);
            tracker.SetValue(owner, new Pawn_DrawTrackerSpecial(owner), BindingFlags .NonPublic| BindingFlags.CreateInstance,null, CultureInfo.CreateSpecificCulture("en-US"));

            //Pawn_DrawTracker re = tracker.GetValue(owner) as Pawn_DrawTracker;
            //tracker.SetValue(re, new Pawn_DrawTrackerSpecial(this));

        }
        public override void ExposeData()
        {
            base.ExposeData();
            if (Scribe.mode == LoadSaveMode.ResolvingCrossRefs)
            {
                FieldInfo tracker = owner.GetType().GetField("drawer", BindingFlags.NonPublic | BindingFlags.Instance);
                tracker.SetValue(owner, new Pawn_DrawTrackerSpecial(owner), BindingFlags.NonPublic | BindingFlags.CreateInstance, null, CultureInfo.CreateSpecificCulture("en-US"));
            }
        }

        public override void SetupField(StandExtension standExtension)
        {
            base.SetupField(standExtension);
            reboundProjectile = standExtension.reboundProjectile;
        }
        public override void Tick()
        {
            base.Tick();
        }

        public override void Draw()
        {
            base.Draw();
        }
        #region 时停相关
        public JitterHandler ReflectionJitter
        {
            get
            {
                if(jitterHandler==null)
                {
                    FieldInfo jtInfo = this.Drawer.GetType().GetField("jitterer", BindingFlags.NonPublic | BindingFlags.Instance);
                    jitterHandler = jtInfo.GetValue(this.Drawer) as JitterHandler;
                }
                return jitterHandler;
            }
        }
        private JitterHandler jitterHandler;

        public override Vector3 DrawPos
        {
            get
            {
                if(this.theWorld)
                {
                    //var realpos = GenThing.TrueCenter(this.Position, this.Rotation, this.def.size, this.def.Altitude);
                    Vector3 tweenedPos = TheWorldDrawPos();
                    tweenedPos += ReflectionJitter.CurrentOffset;
                    tweenedPos += this.Drawer.leaner.LeanOffset;
                    tweenedPos += OffsetForcedByJob();
                    tweenedPos.y = def.Altitude;
                    return tweenedPos;
                }
                return  base.DrawPos;
            }
        }

     

        private Vector3 OffsetForcedByJob()
        {
            if (jobs != null && jobs.curDriver != null)
            {
                return jobs.curDriver.ForcedBodyOffset;
            }
            return Vector3.zero;
        }
        public Vector3 TheWorldDrawPos()
        {
            float movePercent = MovedPercent();
            return pather.nextCell.ToVector3Shifted() * movePercent + Position.ToVector3Shifted() * (1f - movePercent) + PawnCollisionTweenerUtility.PawnCollisionPosOffsetFor(this);
        }
        /// <summary>
		/// 移动百分比
		/// </summary>
		/// <returns></returns>
		private float MovedPercent()
        {
            if (!pather.Moving)
            {
                return 0f;
            }
            if (stances.FullBodyBusy)
            {
                return 0f;
            }
            if (pather.BuildingBlockingNextPathCell() != null)
            {
                return 0f;
            }
            if (pather.NextCellDoorToWaitForOrManuallyOpen() != null)
            {
                return 0f;
            }
            if (pather.WillCollideWithPawnOnNextPathCell())
            {
                return 0f;
            }
            return 1f - pather.nextCellCostLeft / pather.nextCellCostTotal;
        }
        #endregion

        public override void PreApplyDamage(ref DamageInfo dinfo, out bool absorbed)
        {
            if (dinfo.Def == DamageDefOf.Bullet)
            {

                //两个角度的夹角
                float DeltaAngle = Mathf.DeltaAngle(this.Rotation.AsAngle, dinfo.Angle + 180);
                if (this.jobs.curJob.def == StandJobDefOf.CoverMaster || reboundProjectile > Rand.Range(0, 1f))
                {
                    if (Mathf.Abs(DeltaAngle) < 90)
                    {
                        var rangeVerbs = (dinfo.Instigator as Pawn).AllRangedVerbsPawn();
                        foreach (Verb verb in rangeVerbs)
                        {
                            if (verb.GetDamageDef() == dinfo.Def)
                            {
                                //Messages.Message("！", MessageTypeDefOf.NegativeEvent);
                                Verb_LaunchProjectile verb_Launch = (verb as Verb_LaunchProjectile);
                                if (verb_Launch != null)
                                {
                                    Projectile p = ReflectBullet(verb_Launch, ref dinfo);
                                    StandSoundDefOf.OraOra.PlayOneShot(new TargetInfo(this));
                                    Drawer.Notify_MeleeAttackOn(p);
                                }
                                break;
                            }
                        }
                        //(dinfo.Instigator as Pawn).verbTracker.GetVerb(VerbCategory.BeatFire)
                    }
                }
            }
            //this.Rotation.AsAngle;
            base.PreApplyDamage(ref dinfo, out absorbed);
        }



        Projectile ReflectBullet(Verb_LaunchProjectile verb,ref DamageInfo dinfo)
        {

            verb.TryFindShootLineFromTo(this.PositionHeld, dinfo.Instigator, out ShootLine shootLine);
            Projectile projectile = (Projectile)GenSpawn.Spawn(verb.Projectile, this.PositionHeld, this.Map);
             projectile.Launch(this, shootLine.Dest, dinfo.Instigator, ProjectileHitFlags.All);
            //projectile.Launch(this, dinfo.Instigator, dinfo.Instigator, ProjectileHitFlags.All, true);
            dinfo.SetAmount(0);
            return projectile;
        }



    }
}
